
#include "GLSLExtension.h"

PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL;
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL;
PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL;
PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL;
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;

PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL;
PFNGLUNIFORM2FARBPROC glUniform2fARB = NULL;
PFNGLUNIFORM3FARBPROC glUniform3fARB = NULL;
PFNGLUNIFORM4FARBPROC glUniform4fARB = NULL;

PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL;
PFNGLUNIFORM2IARBPROC glUniform2iARB = NULL;
PFNGLUNIFORM3IARBPROC glUniform3iARB = NULL;
PFNGLUNIFORM4IARBPROC glUniform4iARB = NULL;

PFNGLUNIFORM1FVARBPROC glUniform1fvARB = NULL;
PFNGLUNIFORM2FVARBPROC glUniform2fvARB = NULL;
PFNGLUNIFORM3FVARBPROC glUniform3fvARB = NULL;
PFNGLUNIFORM4FVARBPROC glUniform4fvARB = NULL;

PFNGLUNIFORM1IVARBPROC glUniform1ivARB = NULL;
PFNGLUNIFORM2IVARBPROC glUniform2ivARB = NULL;
PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL;
PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL;

#define INITIALIZE_FN_PTR(x,y) x = (y)(SDL_GL_GetProcAddress(#x))

bool InitializeGLSL()
{
    //initlalize all function pointers to the needed functions.
    INITIALIZE_FN_PTR( glCreateProgramObjectARB, PFNGLCREATEPROGRAMOBJECTARBPROC );
    INITIALIZE_FN_PTR( glDeleteObjectARB, PFNGLDELETEOBJECTARBPROC );
    INITIALIZE_FN_PTR( glCreateShaderObjectARB, PFNGLCREATESHADEROBJECTARBPROC );
    INITIALIZE_FN_PTR( glShaderSourceARB, PFNGLSHADERSOURCEARBPROC );
    INITIALIZE_FN_PTR( glCompileShaderARB, PFNGLCOMPILESHADERARBPROC );
    INITIALIZE_FN_PTR( glGetObjectParameterivARB, PFNGLGETOBJECTPARAMETERIVARBPROC );
    INITIALIZE_FN_PTR( glAttachObjectARB, PFNGLATTACHOBJECTARBPROC );
    INITIALIZE_FN_PTR( glGetInfoLogARB, PFNGLGETINFOLOGARBPROC );
    INITIALIZE_FN_PTR( glLinkProgramARB, PFNGLLINKPROGRAMARBPROC );
    INITIALIZE_FN_PTR( glUseProgramObjectARB, PFNGLUSEPROGRAMOBJECTARBPROC );
    INITIALIZE_FN_PTR( glGetUniformLocationARB, PFNGLGETUNIFORMLOCATIONARBPROC );

    INITIALIZE_FN_PTR( glUniform1fARB, PFNGLUNIFORM1FARBPROC );
    INITIALIZE_FN_PTR( glUniform2fARB, PFNGLUNIFORM2FARBPROC );
    INITIALIZE_FN_PTR( glUniform3fARB, PFNGLUNIFORM3FARBPROC );
    INITIALIZE_FN_PTR( glUniform4fARB, PFNGLUNIFORM4FARBPROC );

    INITIALIZE_FN_PTR( glUniform1iARB, PFNGLUNIFORM1IARBPROC );
    INITIALIZE_FN_PTR( glUniform2iARB, PFNGLUNIFORM2IARBPROC );
    INITIALIZE_FN_PTR( glUniform3iARB, PFNGLUNIFORM3IARBPROC );
    INITIALIZE_FN_PTR( glUniform4iARB, PFNGLUNIFORM4IARBPROC );

    INITIALIZE_FN_PTR( glUniform1fvARB, PFNGLUNIFORM1FVARBPROC );
    INITIALIZE_FN_PTR( glUniform2fvARB, PFNGLUNIFORM2FVARBPROC );
    INITIALIZE_FN_PTR( glUniform3fvARB, PFNGLUNIFORM3FVARBPROC );
    INITIALIZE_FN_PTR( glUniform4fvARB, PFNGLUNIFORM4FVARBPROC );

    INITIALIZE_FN_PTR( glUniform1ivARB, PFNGLUNIFORM1IVARBPROC );
    INITIALIZE_FN_PTR( glUniform2ivARB, PFNGLUNIFORM2IVARBPROC );
    INITIALIZE_FN_PTR( glUniform3ivARB, PFNGLUNIFORM3IVARBPROC );
    INITIALIZE_FN_PTR( glUniform4ivARB, PFNGLUNIFORM4IVARBPROC );

    //make sure that all functions were loaded properly.
    return(glCreateProgramObjectARB && glDeleteObjectARB &&
            glCreateShaderObjectARB && glShaderSourceARB &&
            glCompileShaderARB && glGetObjectParameterivARB &&
            glAttachObjectARB && glGetInfoLogARB && glLinkProgramARB &&
            glUseProgramObjectARB && glGetUniformLocationARB &&
            glUniform1fARB && glUniform1iARB );
}